package spsu.swe6733.assignment2;

import static org.junit.Assert.*;

import java.io.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class PositiveIntegerUnitTest{

	private PositiveInteger pInt1 = new PositiveInteger();	
	private PositiveInteger pInt2 = new PositiveInteger();	
	private String s;
	
	
	
		@Test										//Test lower boundary positive integer "1"
		public void validPosIntLB() {
			
			s="1";
			pInt1.setN(s);		
			assertEquals("setN-getN Error!",1,pInt1.getN());
			assertTrue("isValid Error!",pInt1.isValid());
			assertEquals("validatePosInteger() Error!",1,pInt2.validatePosInteger(s));
			
		}
		
		@Test										//Test upper boundary positive integer in Java "2147483647"
		public void validPosIntJavaUB() {
			s=("2147483647");
			pInt1.setN(s);
			assertEquals("setN-getN Error!",2147483647,pInt1.getN());
			assertTrue("isValid Error!",pInt1.isValid());
			assertEquals("validatePosInteger() Error!",2147483647,pInt2.validatePosInteger(s));
		}
			
		@Test										//Test upper boundary  integer exception thrown in Java "2147483648"
		public void javaUBNonIntException()
		{
			s=("2147483648");
			pInt1.setN("2147483648");
			assertEquals("setN-getN Error!",0,pInt1.getN());
			assertFalse("isValid Error!",pInt1.isValid());
			assertEquals("validatePosInteger() Error!",0,pInt2.validatePosInteger(s));
			
		}	
		
		@Test										//Test lower boundary integer exception thrown in Java "-2147483649"
		public void javaLBNonIntException()
		{
			s=("-2147483649");
			pInt1.setN("-2147483649");
			assertEquals("setN-getN Error!",0,pInt1.getN());
			assertFalse("isValid Error!",pInt1.isValid());
			assertEquals("validatePosInteger() Error!",0,pInt2.validatePosInteger(s));
			
		}	
			;
		@Test										//Test numberFormatException thrown for null 
		public void nullNonIntException() 
		{
			s=("");
			pInt1.setN(s);
			assertEquals("setN-getN Error!",0,pInt1.getN());
			assertFalse("isValid Error!",pInt1.isValid());
			assertEquals("validatePosInteger() Error!",0,pInt2.validatePosInteger(s));
		}
		
		@Test										//Test numberFormatException thrown for a char
		public void charNonIntException() 
		{
			s=("@");
			pInt1.setN(s);
			assertEquals("setN-getN Error!",0,pInt1.getN());
			assertFalse("isValid Error!",pInt1.isValid());
			assertEquals("validatePosInteger() Error!",0,pInt2.validatePosInteger(s));
	}
		
		@Test										//Test numberFormatException thrown for a string
		public void stringNonIntException() 
		{
			s=("Hello World!");
			pInt1.setN(s);
			assertEquals("setN-getN Error!",0,pInt1.getN());
			assertFalse("isValid Error!",pInt1.isValid());
			assertEquals("validatePosInteger() Error!",0,pInt2.validatePosInteger(s));
		}
		
		@Test										//Test numberFormatException thrown for a double
		public void doubleNonIntException() 
		{
			s=("3.14");
			pInt1.setN(s);
			assertEquals("setN-getN Error!",0,pInt1.getN());
			assertFalse("isValid Error!",pInt1.isValid());
			assertEquals("validatePosInteger() Error!",0,pInt2.validatePosInteger(s));
		}
		
		@Test										//Test nonPositiveNumberExeception thrown for "0"
		public void zeroNonPosIntException() 
		{
			s=("0");
			pInt1.setN(s);
			assertEquals("setN-getN Error!",-1,pInt1.getN());
			assertFalse("isValid Error!",pInt1.isValid());
			assertEquals("validatePosInteger() Error!",-1,pInt2.validatePosInteger(s));
			
		}
		
		@Test										//Test nonPositiveNumberExeception thrown for "-1" - upper boundary
		public void negNonPosIntExceptionUB() 
		{
			s=("-1");
			pInt1.setN(s);
			assertEquals("setN-getN Error!",-1,pInt1.getN());
			assertFalse("isValid Error!",pInt1.isValid());
			assertEquals("validatePosInteger() Error!",-1,pInt2.validatePosInteger(s));
		}
		
		@Test										//Test nonPositiveNumberExeception thrown for "-2147483648" - lower boundary
		public void negNonPosIntExceptionLB() 
		{
			s=("-2147483648");
			pInt1.setN(s);
			assertEquals("setN-getN Error!",-1,pInt1.getN());
			assertFalse("isValid Error!",pInt1.isValid());
			assertEquals("validatePosInteger() Error!",-1,pInt2.validatePosInteger(s));
		}	
		@Test										//Test lower boundary of the loopSum method - "1"
		public void loopLB()
		{
			pInt1.setN("1");
			assertEquals("loopSumLB Error!",1,pInt1.loopSum());
		}
		
		@Test										//Test upper boundary of the loopSum method - "2147483647"
		public void loopUB() {
			pInt1.setN("2147483647");
			assertEquals("loopSumUB Error!",2305843008139952128L,pInt1.loopSum());
		}
		
		@Test										//Test the base case for the recursiveSum method - "1"
		public void recursiveBaseCase()
		{
			pInt1.setN("1");
			assertEquals("recursiveBaseCase Error!",1,pInt1.recursiveSum(pInt1.getN()));
		}
		
		@Test										//Test the base case +1 for the recursiveSum method - "2"
		public void recursiveBaseCasePlus1()
		{
			pInt1.setN("2");
			assertEquals("recursiveBaseCasePlus1 Error!",3,pInt1.recursiveSum(pInt1.getN()));
		}
		
		@Test										//Test the base case +2 for the recursiveSum method - "3"
		public void recursiveBaseCasePlus2()
		{
			pInt1.setN("3");
			assertEquals("recursiveBaseCasePlus2 Error!",6,pInt1.recursiveSum(pInt1.getN()));
		}

		@Test										//Test the recursiveSum method before a stackOverflowException is thrown. 
		public void recursiveAproachingStackOverflow()
		{
			pInt1.setN("8000");
			assertEquals("recursiveApproachingStackOverflow Error!",32004000L,pInt1.recursiveSum(pInt1.getN()));
		}
		
		@Test										//Test that the StackOverflowException is thrown in the recursiveSum method.
		public void recursiveStackOverflowException()
		{
			pInt1.setN("10000");
			assertTrue("recursiveStackOverflowException Error!",pInt1.arithmeticSum() > pInt1.recursiveSum(pInt1.getN()));
		}	
		
		@Test										//Test lower boundary of the arithmeticSum method - "1"
		public void arithmeticLB()
		{
			pInt1.setN("1");
			assertEquals("arithmeticSumLB Error!",1,pInt1.arithmeticSum());
		}
		
		@Test										//Test upper boundary of the arithmeticSum method - "2147483647"
		public void arithmeticUB() {
			pInt1.setN("2147483647");
			assertEquals("arithmeticSumUB Error!",2305843008139952128L,pInt1.arithmeticSum());
		}
		
		@Test										//Test isValid method given a valid positive integer
		public void isValidTrue() {
			pInt1.setN("1");
			assertTrue("isValid True Error!",pInt1.isValid());
		}
		@Test										//Test isValid method given an invalid input
		public void isValidFalse() {
			pInt1.setN("0");
			assertFalse("isValid FalseError!",pInt1.isValid());
		}
	}

